package com.qzl.server.server;

import com.qzl.common.netty.handler.ExceptionHandler;
import com.qzl.server.handler.BusinessHandler;
import com.qzl.server.handler.ProtocolSwitchHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.net.InetSocketAddress;

/**
 * @author: qzl
 * @date : 2025/6/30 15:46
 * @description:
 */
@Component
public class SpringNettyServer {
    // 从配置文件中读取端口号，默认8848
    @Value("${netty.port:8848}")
    private int port;

    // 主线程组，用于接收客户端连接
    private EventLoopGroup bossGroup;
    // 工作线程组，用于处理网络读写
    private EventLoopGroup workerGroup;


    /**
     * 启动Netty服务器
     * 使用@PostConstruct注解在Spring Bean初始化后执行
     */
    @PostConstruct
    public void start() throws InterruptedException {
        // 创建主线程组，接收客户端连接
        bossGroup = new NioEventLoopGroup(1); // 1个线程足够
        // 创建工作线程组，处理网络读写
        workerGroup = new NioEventLoopGroup(); // 默认CPU核心数*2

        // 创建服务器启动对象
        ServerBootstrap bootstrap = new ServerBootstrap();
        bootstrap.group(bossGroup, workerGroup)
                // 使用NioServerSocketChannel作为服务器通道实现
                .channel(NioServerSocketChannel.class)
                // 设置服务器监听端口
                .localAddress(new InetSocketAddress(port))
                // 初始化通道，设置处理器
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        // ch.pipeline().addLast(new LoggingHandler(LogLevel.DEBUG));
                        // 协议检测处理器：决定是 WebSocket 还是自定义协议
                        ch.pipeline().addLast(new ProtocolSwitchHandler());
                        // 添加自定义处理器
                        ch.pipeline().addLast(new BusinessHandler());
                        // 异常处理器
                        ch.pipeline().addLast(new ExceptionHandler());
                    }
                })
                // 服务器等待队列大小
                .option(ChannelOption.SO_BACKLOG, 128)
                // 保持长连接
                .childOption(ChannelOption.SO_KEEPALIVE, true);

        // 绑定端口启动服务器
        ChannelFuture future = bootstrap.bind().sync();
        if (future.isSuccess()) {
            System.out.println("Netty server started on port: " + port);
        }
    }

    /**
     * 关闭Netty服务器
     * 使用@PreDestroy注解在Spring Bean销毁前执行
     */
    @PreDestroy
    public void stop() {
        // 优雅关闭线程组
        if (bossGroup != null) {
            bossGroup.shutdownGracefully();
        }
        if (workerGroup != null) {
            workerGroup.shutdownGracefully();
        }
        System.out.println("Netty server stopped");
    }
}
